package com.ctrip.coverage.web.view.codecoverage;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.bstek.dorado.annotation.DataProvider;
import com.bstek.dorado.annotation.Expose;
import com.bstek.dorado.data.entity.EntityUtils;
import com.ctrip.coverage.model.entity.NetCoverageClassEntity;
import com.ctrip.coverage.model.entity.NetCoverageEntity;
import com.ctrip.coverage.model.entity.NetCoverageLinesEntity;
import com.ctrip.coverage.model.entity.NetCoverageMethodEntity;
import com.ctrip.coverage.model.entity.NetCoverageModuleEntity;
import com.ctrip.coverage.model.entity.NetCoverageNamespaceTableEntity;
import com.ctrip.coverage.model.entity.TfsFolderEntity;
import com.ctrip.coverage.orm.dao.BaseDaoI;
import com.ctrip.coverage.service.AutoBuild;
import com.ctrip.coverage.service.AutoBuildPublish;
import com.ctrip.coverage.service.CoverageWebService;
import com.ctrip.coverage.service.NetCodeCoverageService;
import com.ctrip.coverage.utils.config.RCConfig;
import com.ctrip.coverage.utils.enums.LanguageType;
import com.ctrip.coverage.utils.enums.ProjectType;

@Component
public class CodeCoverage {

	@Autowired
	BaseDaoI<NetCoverageEntity> netCoverageEntityDao;
	@Autowired
	NetCodeCoverageService netCodeCoverageService;
	@Autowired
	BaseDaoI<NetCoverageModuleEntity> netCoverageModuleDao;
	@Autowired
	BaseDaoI<NetCoverageNamespaceTableEntity> netCoverageNamespaceTableDao;
	@Autowired
	BaseDaoI<NetCoverageClassEntity> netCoverageClassDao;
	@Autowired
	BaseDaoI<NetCoverageMethodEntity> netCoverageMethodDao;
	@Autowired
	BaseDaoI<TfsFolderEntity> tfsFolderDao;
	@Autowired
	BaseDaoI<NetCoverageLinesEntity> netCoverageLinesDao;
	@Autowired
	AutoBuild autoBuild;
	@Autowired
	RCConfig config;
	@Autowired
	CoverageWebService coverageWebServiceClient;

	@Autowired
	AutoBuildPublish autoBuildPublish;

	@DataProvider
	public Collection<TfsFolderEntity> getTfsFolderEntity(Integer parentId) throws Exception {
		List<TfsFolderEntity> tfsFolderEntityList = tfsFolderDao.find("from TfsFolderEntity where parent.id=" + parentId);
		List<TfsFolderEntity> tfsFolderEntityListNew = new ArrayList<TfsFolderEntity>();
		for (TfsFolderEntity tfsFolderEntity : tfsFolderEntityList) {
			TfsFolderEntity tfsFolderEntityNew = EntityUtils.toEntity(tfsFolderEntity);
			if (tfsFolderEntity.getType() == ProjectType.SOLUTION) {
				EntityUtils.setValue(tfsFolderEntityNew, "treeIcon", "url(>skin>common/icons.gif) -200px -80px");
			} else {
				EntityUtils.setValue(tfsFolderEntityNew, "treeIcon", " url(>skin>common/icons.gif) -260px -40px");
			}
			if (tfsFolderEntity.getType() == ProjectType.PROJECT) {
				if (null != tfsFolderEntity.getIsCoverage() && tfsFolderEntity.getIsCoverage() == 1) {
					tfsFolderEntityListNew.add(tfsFolderEntityNew);
				}
			} else {
				tfsFolderEntityListNew.add(tfsFolderEntityNew);
			}
		}

		return tfsFolderEntityListNew;
	}

	@DataProvider
	public Collection<TfsFolderEntity> getTfsFolderEntityRoot() throws Exception {
		List<TfsFolderEntity> tfsFolderEntityList = tfsFolderDao.find("from TfsFolderEntity where type=1");
		List<TfsFolderEntity> tfsFolderEntityListNew = new ArrayList<TfsFolderEntity>();
		for (TfsFolderEntity tfsFolderEntity : tfsFolderEntityList) {
			TfsFolderEntity tfsFolderEntityNew = EntityUtils.toEntity(tfsFolderEntity);
			if (tfsFolderEntity.getType() == ProjectType.SOLUTION) {
				EntityUtils.setValue(tfsFolderEntityNew, "treeIcon", "url(>skin>common/icons.gif) -200px -80px");
			} else {
				EntityUtils.setValue(tfsFolderEntityNew, "treeIcon", " url(>skin>common/icons.gif) -260px -40px");
			}
			if (tfsFolderEntity.getType() == ProjectType.PROJECT) {
				if (null != tfsFolderEntity.getIsCoverage() && tfsFolderEntity.getIsCoverage() == 1) {
					tfsFolderEntityListNew.add(tfsFolderEntityNew);
				}
			} else {
				tfsFolderEntityListNew.add(tfsFolderEntityNew);
			}
		}

		return tfsFolderEntityListNew;
	}

	@DataProvider
	public Collection<NetCoverageEntity> getNetCoverageEntity(String nodeKey) {
		List<NetCoverageEntity> netCoverageListNew = new ArrayList<NetCoverageEntity>();
		List<TfsFolderEntity> tfsFolderEntityList = tfsFolderDao.find("FROM TfsFolderEntity WHERE type=4 and nodeKey LIKE '" + nodeKey + "%'");
		for (TfsFolderEntity tfsFolderEntity : tfsFolderEntityList) {
			List<NetCoverageEntity> netCoverageList = netCoverageEntityDao.find("from NetCoverageEntity where tfsFolder.id=" + tfsFolderEntity.getId()
					+ "order by  version ASC,id ASC");
			for (NetCoverageEntity netCoverageEntity : netCoverageList) {
				int BlocksCovered = netCoverageEntity.getBlocksCovered();
				int BlocksNotCovered = netCoverageEntity.getBlocksNotCovered();
				int linesCoveraged = netCoverageEntity.getLinesCovered();
				int linesLinesNotCovered = netCoverageEntity.getLinesNotCovered();
				int linesPartiallyCovered = netCoverageEntity.getLinesPartiallyCovered();
				int linesTotal = linesCoveraged + linesLinesNotCovered + linesPartiallyCovered;
				float linesRate = (float) (linesCoveraged + linesPartiallyCovered) / (float) linesTotal;
				float linesNoRate = (float) (linesLinesNotCovered) / (float) linesTotal;
				float blocksRate = (float) BlocksCovered / (float) (BlocksCovered + BlocksNotCovered);
				netCoverageEntity.setLinesTotalCount(linesTotal);
				netCoverageEntity.setBlocksRate((float) (Math.floor(blocksRate * 10000)) / 10000);
				netCoverageEntity.setLinesRate((float) (Math.floor(linesRate * 10000)) / 10000);
				netCoverageEntity.setLinesNoRate((float) (Math.floor(linesNoRate * 10000)) / 10000);
				netCoverageEntity.setTotalLines(linesTotal);
				netCoverageListNew.add(netCoverageEntity);
			}
		}

		return netCoverageListNew;
	}

	@Expose
	@Transactional
	public void deleteNetCoverageEntity(Collection<NetCoverageEntity> netCoverageEntityCollection) {
		netCodeCoverageService.deleteNetCoverage(netCoverageEntityCollection);
	}

	@DataProvider
	public Collection<NetCoverageModuleEntity> getNetCoverageModuleEntity(Integer netCoverageId) {
		return netCoverageModuleDao.find("from NetCoverageModuleEntity where netCoverage.id=" + netCoverageId);
	}

	@DataProvider
	public Collection<NetCoverageNamespaceTableEntity> getNetCoverageNamespaceTableEntity(Integer netCoverageModuleId) {
		return netCoverageNamespaceTableDao.find("from NetCoverageNamespaceTableEntity where netCoverageModule.id=" + netCoverageModuleId);
	}

	@DataProvider
	public Collection<NetCoverageClassEntity> getNetCoverageClassEntity(Integer netCoverageNamespaceTableId) {
		return netCoverageClassDao.find("from NetCoverageClassEntity where netCoverageNamespaceTable.id=" + netCoverageNamespaceTableId);
	}

	@DataProvider
	public Collection<NetCoverageMethodEntity> getNetCoverageMethodEntity(Integer netCoverageClassEntityId) {
		return netCoverageMethodDao.find("from NetCoverageMethodEntity where netCoverageClass.id=" + netCoverageClassEntityId);
	}

	@DataProvider
	public Collection<NetCoverageLinesEntity> getNetCoverageLinesEntity(Integer NetCoverageMethodEntityId) {
		return netCoverageLinesDao.find("from NetCoverageLinesEntity where netCoverageMethod.id=" + NetCoverageMethodEntityId);
	}

	@Expose
	@Transactional
	public void mergeCoverage(List<NetCoverageEntity> netCoverageList, TfsFolderEntity tfsFolderEntity) throws Exception {
		NetCoverageEntity startCoverage;
		NetCoverageEntity endCoverage;

		Collections.sort(netCoverageList, new Comparator<NetCoverageEntity>() {
			public int compare(NetCoverageEntity arg0, NetCoverageEntity arg1) {
				int flag = arg1.getVersion().compareTo(arg0.getVersion());
				if (flag == 0) {
					return Integer.valueOf(arg1.getId()).compareTo(Integer.valueOf(arg0.getId()));
				} else {
					return flag;
				}
			}
		});

		for (int i = 0; i < netCoverageList.size() - 1; i++) {
			endCoverage = netCoverageList.get(i);
			startCoverage = netCoverageList.get(i + 1);
			endCoverage = netCoverageEntityDao.get("from NetCoverageEntity where id=?", endCoverage.getId());

			if (startCoverage.getVersion().equals(endCoverage.getVersion())) {
				netCodeCoverageService.merageSameVersion(startCoverage, endCoverage);
			} else {
				netCodeCoverageService.meragDiffVersion(startCoverage, endCoverage, tfsFolderEntity);
			}
		}
	}

	@Expose
	public void merageSolution(List<TfsFolderEntity> tfsFolderList) {
		netCodeCoverageService.merageSolution(tfsFolderList);
	}

	@Expose
	public void autoPublish(List<TfsFolderEntity> tfsFolderList) {
		for (TfsFolderEntity tfsFolderEntity : tfsFolderList) {
			if (tfsFolderEntity.getLanguage() == LanguageType.CSHARP) {
				autoBuildPublish.csharpBuildPublish(tfsFolderEntity);
			} else if (tfsFolderEntity.getLanguage() == LanguageType.JAVA) {
				autoBuildPublish.javaBuildPublish();
			}
		}
	}

	@Expose
	public void coverageMonitor() {
		Date date = new Date();
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

		String coverageout = format.format(date).toString();
		coverageWebServiceClient.coverageMonitor(config.getBatPath(), config.getCoverageInterfaceTestPath() + "\\out\\" + coverageout + ".coverage");
	}

	@Expose
	public void collectCoverage() {
		try {
			coverageWebServiceClient.collectCoverage(config.getBatPath());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Expose
	public void deleteWorkSpace() {
		autoBuild.deleteWorkSpace();
		coverageWebServiceClient.deleteWorkSpace(config.getBatPath());
	}
}
